package com.proyecto.robomind.interpreter;

import com.proyecto.robomind.map.MapHandler;
import com.proyecto.robomind.model.MapSquare;
import com.proyecto.robomind.model.Ninja;

public class Interpreter {
	
	int rowCount;
	int lineCount;
	int scriptId;
	String script;
	String[] instructions;
	
	Thread thread;
	Ninja ninja;
	MapSquare[][] currentMap;
	boolean running = false;
	
	boolean isInstructionOnCourse= false;
	String instructionOnCourse;
	int repetitionCount;
	
	public Interpreter(Ninja ninja, MapSquare[][] currentMap){
		this.ninja = ninja;
		this.currentMap = currentMap;
		thread = new Thread(new Runnable(){

			public void run() {
				// TODO Auto-generated method stub
				while(true){
					while(running){
						if(!isInstructionOnCourse){
							processNextInstruction(rowCount);
							rowCount++;
						}else{
							runInstruction();
						}
						try {
							Thread.sleep(300);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				}
			}
			
		});
		thread.start();
	}
	
	public void setScript(String script){
		this.script = script;
		instructions = composeScript(script);
		restartInstructions();
	}
	
	public String[] composeScript(String script){
		String scriptFixed = script.replaceAll("\n", ";");
		scriptFixed = scriptFixed.replaceAll(" ","");
		String[] instructions = scriptFixed.split(";");
		return instructions;
	}
	
	public void restartInstructions(){
		rowCount = 0;
	}
	
	public void setThreadRunning(boolean running){
		this.running = running;
	}
	
	public void processNextInstruction(int rowCount){
		if(rowCount>=instructions.length){
			running = false;
		}else{
			String instructionLine = instructions[rowCount];
			String[] instructionModified = null;
	
			if(instructionLine.contains("(")){
				instructionModified = instructionLine.split("\\(");
				instructionOnCourse = instructionModified[0];
				if(instructionModified[1].length()>1){
					repetitionCount = (int)instructionModified[1].charAt(0) - 48;
				}
				if(instructionModified[1].length()>2){
					repetitionCount*=10;
					repetitionCount += (int)instructionModified[1].charAt(1) - 48;
				}
				isInstructionOnCourse = true;
				if(instructionOnCourse.toLowerCase().equals("forward")){
					repetitionCount *= 5;
				}
			}
		}
	}
	
	public void runInstruction(){
		if(repetitionCount!=0){
			MapSquare map = MapHandler.getNextMap(currentMap, ninja.getX(), ninja.getY(), ninja.getOrientation());
			if(instructionOnCourse.toLowerCase().equals("right")){
				ninja.goRight(1);
			}else if(instructionOnCourse.toLowerCase().equals("left")){
				ninja.goLeft(1);
			}else if(instructionOnCourse.toLowerCase().equals("forward")){
				if(map!=null && map.getCharacter().equals("e")){
					ninja.goForward(1);
				}
			}else if(instructionOnCourse.toLowerCase().equals("push")){
				if(map!=null && ninja.hasObj()){
					map = ninja.push();
				}
			}else if(instructionOnCourse.toLowerCase().equals("get")){
				if(map!=null){
					ninja.get(map);
					MapHandler.removeMap(currentMap, map);
					
				}
			}
			repetitionCount--;
		}else{
			isInstructionOnCourse = false;
		}
	}
	
	public void right(int x){}
	
	public void left(int x){}
	
	public void forward(int x){}
	
	public void get(){}
	
	public void push(){}
	
	public void repeat(){}
}
